package com.qinggeng.project.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.qinggeng.common.constant.Constants;
import com.qinggeng.common.enums.*;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.MessageUtils;
import com.qinggeng.common.utils.ServletUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.common.utils.http.HttpUtils;
import com.qinggeng.framework.manager.AsyncManager;
import com.qinggeng.framework.manager.factory.AsyncFactory;
import com.qinggeng.framework.security.LoginUser;
import com.qinggeng.framework.web.controller.BaseController;
import com.qinggeng.framework.web.domain.AjaxResult;
import com.qinggeng.project.api.dto.LoginDto;
import com.qinggeng.project.api.dto.UserBindDto;
import com.qinggeng.project.api.dto.WxMiniLoginParamsDTO;
import com.qinggeng.project.api.security.annotation.LoginRequired;
import com.qinggeng.project.api.security.utils.ApiUtils;
import com.qinggeng.project.api.service.IApiMemberService;
import com.qinggeng.project.api.utils.PhoneNumberUtils;
import com.qinggeng.project.system.domain.*;
import com.qinggeng.project.system.service.*;
import com.qinggeng.project.tool.sms.service.ISysSmsService;
import com.qinggeng.project.tool.third.domain.SysThird;
import com.qinggeng.project.tool.third.domain.SysThirdPlatform;
import com.qinggeng.project.tool.third.domain.vo.Jscode2SessionBean;
import com.qinggeng.project.tool.third.mapper.SysThirdPlatformMapper;
import com.qinggeng.project.tool.third.service.ISysThirdPlatformService;
import com.qinggeng.project.tool.third.service.ISysThirdService;
import com.qinggeng.project.tool.third.utils.MiniappUtils;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Api(tags = "登录模块")
@RestController
@RequestMapping("${apiPath}")
public class ApiLoginController extends BaseController {

    @Autowired
    private IApiMemberService memberService;

    @Autowired
    private ISysThirdPlatformService thirdPlatformService;

    @Autowired
    private ISysSmsService smsService;

    @Autowired
    private IShopService shopService;

    @Autowired
    private ISysThirdService thirdService;

    @Resource
    private SysThirdPlatformMapper sysThirdPlatformMapper;

    @Autowired
    private IUserAliasService userAliasService;

    @Autowired
    private UserBindService userBindService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private DeviceBindPhoneService deviceBindPhoneService;

    @Autowired
    private UserBindGsdService userBindGsdService;


    @ApiOperation("手机号登录")
    @PostMapping("/phoneLogin")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userType", value = "用户类型 10=普通会员 20=配送员", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userAlias", value = "用户别名", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "wxCode", value = "授权码", dataType = "String", paramType = "query",required = false),
    })
    public AjaxResult phoneLogin(String phone, String password, String userType, String userAlias,@RequestParam(name = "wxCode", defaultValue = "")String wxCode,@RequestParam(name = "deviceNo",defaultValue = "") String deviceNo) {
        SysUser sysUser = memberService.selectByPhone(phone, userType);
        if (sysUser == null) {
            return AjaxResult.error("手机号不存在", ShowTypeEnum.用户.getValue());
        }

        if (!ApiUtils.matchesPassword(password, sysUser.getPassword())) {
            return AjaxResult.error("密码错误",ShowTypeEnum.用户.getValue());
        }

        if (sysUser.getStatus().equals(StatusEnum.DISABLE.getCode())) {
            throw new CustomException("账号已停用，请联系管理员",ShowTypeEnum.用户.getValue());
        }

        try {
            String deviceBind = sysUser.getDeviceBind();
            if (!StringUtils.isEmpty(deviceNo) && DeviceBindEnum.TWO.getValue().equals(deviceBind)) {
                bindDevice(deviceNo,phone,sysUser);
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }
        Map<String, Object> data = Maps.newHashMap();
        LoginUser apiLoginUser = new LoginUser(sysUser);

        //绑定openId
        if (!StringUtils.isEmpty(wxCode) && StringUtils.isEmpty(sysUser.getOpenId())){
            String openId = getOpenId(wxCode);
            sysUser.setOpenId(openId);
            memberService.updateMember(sysUser);
        }
        //如果登录用户为骑手
        if (userType.equals(UserTypeEnum.COURIER.getCode())) {
            data.put("jpushLabel", ApiUtils.DEFAULT_ROLE_COURIER + apiLoginUser.getUser().getRegisterCode());
            //更新骑手登录信息
            data.put("token", updateCourierToken(sysUser,apiLoginUser,userAlias));
            return AjaxResult.success(data);
        }

        if (userType.equals(UserTypeEnum.MEMBER.getCode())) {
            apiLoginUser.setRole(ApiUtils.DEFAULT_ROLE_USER);
        }
        //更新普通用户登录信息
        data.put("token", updateMemberToken(sysUser,apiLoginUser,userAlias));
        return AjaxResult.success(data);
    }



    @ApiOperation("手机号加验证码登录 没有账号自动注册")
    @PostMapping("/phoneCodeLogin")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userType", value = "用户类型 10=普通会员 20=配送员", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userAlias", value = "用户别名", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "wxCode", value = "授权码", dataType = "String", paramType = "query",required = false),
    })
    public AjaxResult phoneCodeLogin(String phone, String code, String userType, String userAlias,@RequestParam(name = "wxCode",defaultValue = "")String wxCode,@RequestParam(name = "deviceNo",defaultValue = "") String deviceNo) {
        if (!PhoneNumberUtils.isMobile(phone)){
            return AjaxResult.error("号码格式错误,请重新输入",ShowTypeEnum.用户.getValue());
        }
        if (StringUtils.isEmpty(userType)) {
            return AjaxResult.error("用户类型不能为空");
        }
        String checkCode = smsService.getCode(phone, "login");
        if (StringUtils.isEmpty(checkCode) || !code.equals(checkCode)) {
            return AjaxResult.error("验证码错误",ShowTypeEnum.用户.getValue());
        }
        SysUser sysUser = memberService.selectByPhone(phone, userType);
        if (sysUser == null) {
            memberService.insertPhone(phone, null, null, userType);
            sysUser = memberService.selectByPhone(phone, userType);
        }
        if (sysUser.getStatus().equals(StatusEnum.DISABLE.getCode())) {
            throw new CustomException("账号已停用，请联系管理员",ShowTypeEnum.用户.getValue());
        }
        smsService.remove(phone, "login");

        try {
            String deviceBind = sysUser.getDeviceBind();
            if (!StringUtils.isEmpty(deviceNo) && DeviceBindEnum.TWO.getValue().equals(deviceBind)) {
                bindDevice(deviceNo,phone,sysUser);
            }
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }

        //绑定openId
        if (!StringUtils.isEmpty(wxCode) && StringUtils.isEmpty(sysUser.getOpenId())){
            String openId = getOpenId(wxCode);
            sysUser.setOpenId(openId);
            memberService.updateMember(sysUser);
        }
        LoginUser apiLoginUser = new LoginUser(sysUser);
        Map<String, String> data = Maps.newHashMap();
        //如果用户类型为骑手
        if (userType.equals(UserTypeEnum.COURIER.getCode())) {
            data.put("jpushLabel", ApiUtils.DEFAULT_ROLE_COURIER + apiLoginUser.getUser().getRegisterCode());
            //更新骑手登录信息
            data.put("token",updateCourierToken(sysUser,apiLoginUser,userAlias));
            return AjaxResult.success(data);
        }
        if (userType.equals(UserTypeEnum.MEMBER.getCode())) {
            apiLoginUser.setRole(ApiUtils.DEFAULT_ROLE_USER);
        }
       //更新普通用户登录信息
        data.put("token",updateMemberToken(sysUser,apiLoginUser,userAlias));
        return AjaxResult.success(data);
    }

    @ApiOperation("获取oepnid和sessionKey")
    @PostMapping("/getOpenIdAndSessionkey")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "微信授权编码", dataType = "String", paramType = "query"),

    })
    public AjaxResult getOpenIdAndSessionkey(String code){
        try {
            SysThirdPlatform thirdPlatform = sysThirdPlatformMapper.selectSysThirdPlatformByCode("wx_mini");

            //封装openid 和 sessionkey
            HashMap<String, String> data = Maps.newHashMap();

            Map<String, String> jscode2SessionQuerys = Maps.newHashMap();
            jscode2SessionQuerys.put("appid", thirdPlatform.getAppId());
            jscode2SessionQuerys.put("secret", thirdPlatform.getAppSecret());
            jscode2SessionQuerys.put("js_code", code);
            jscode2SessionQuerys.put("grant_type","authorization_code");
            HttpResponse jscode2SessionResponse = HttpUtils.doGet("https://api.weixin.qq.com", "/sns/jscode2session", null, jscode2SessionQuerys);
            Jscode2SessionBean jscode2Session = JSON.parseObject(EntityUtils.toString(jscode2SessionResponse.getEntity(), "UTF-8"),Jscode2SessionBean.class);
            if(StringUtils.isBlank(jscode2Session.getOpenid())&&StringUtils.isBlank(jscode2Session.getSessionKey())){
                throw new CustomException("未获取到用户openid 或 session:"+JSON.toJSONString(jscode2Session));
            }
            data.put("openid",jscode2Session.getOpenid());
            data.put("sessionKey",jscode2Session.getSessionKey());
            return AjaxResult.success(data);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());

        }
    }

    @ApiOperation("微信小程序登录")
    @PostMapping("/wxMiniLogin")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sessionKey", value = "sessionKey", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "encryptedData", value = "加密值", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "iv", value = "iv值", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userType", value = "用户类型 10=普通会员 20=配送员", dataType = "String", paramType = "query"),
    })
    public AjaxResult wxMiniLogin(WxMiniLoginParamsDTO wxMiniLoginParamsDTO) {
        String userType = wxMiniLoginParamsDTO.getUserType();
        if (StringUtils.isEmpty(userType)){
            throw new CustomException("用户类型为空 userType is null");
        }

        String sessionKey = wxMiniLoginParamsDTO.getSessionKey();
        if (StringUtils.isEmpty(sessionKey)){
            throw new CustomException("sessionKey is "+sessionKey);
        }
        String iv = wxMiniLoginParamsDTO.getIv();
        if (StringUtils.isEmpty(iv)){
            throw new CustomException("iv is "+iv);
        }
        String encryptedData = wxMiniLoginParamsDTO.getEncryptedData();
        if (StringUtils.isEmpty(encryptedData)){
            throw new CustomException("encryptedData is "+encryptedData);
        }
        if (userType.equals(UserTypeEnum.COURIER.getCode())) {
            return AjaxResult.error("请使用APP登录",ShowTypeEnum.用户.getValue());
        }
        try {
            encryptedData = encryptedData.replaceAll(" ","+");
            iv = iv.replaceAll(" ", "+");
            sessionKey.replaceAll(" ","+");
            SysThird third = thirdPlatformService.wxMinToThirdInfo(encryptedData,iv,sessionKey);
            SysUser sysUser = memberService.selectMemberById(third.getUserId());
            LoginUser apiLoginUser = new LoginUser(sysUser);
            if (userType.equals(UserTypeEnum.MEMBER.getCode())) {
                apiLoginUser.setRole(ApiUtils.DEFAULT_ROLE_USER);
            }
            //如果没有绑定手机号码
            if(sysUser.getPhonenumber().isEmpty()) {
                return AjaxResult.success(LoginDto.getLoginDto(sysUser.getUserId(),"0",""));
            }
            //更新登录信息
            String token=updateMemberToken(sysUser,apiLoginUser,null);
            return AjaxResult.success(LoginDto.getLoginDto(sysUser.getUserId(),"1",token));
        } catch (Exception e) {
            return AjaxResult.error("授权登录失败:" + e.getMessage());
        }
    }
    @ApiOperation("微信小程序获取手机号")
    @PostMapping("/getPhoneNumber")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "微信授权编码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "encryptedData", value = "加密值", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "iv", value = "iv值", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "用户Id", dataType = "long", paramType = "query"),
    })
    public AjaxResult getPhoneNumber(String encryptedData, String session_key, String iv,Long userId) {
        try {
            HashMap<String, String> data = Maps.newHashMap();
            encryptedData = encryptedData.replaceAll(" ","+");
            iv = iv.replaceAll(" ","+");
            session_key = session_key.replaceAll(" ", "+");
            //解密获取用户信息
            String userInfo = MiniappUtils.wxDecrypt(encryptedData, session_key, iv);
            //解析
            String phoneNumber = JSON.parseObject(userInfo).getString("phoneNumber");
            //根据手机号码查询用户
            SysUser sysUser = memberService.selectByPhone(phoneNumber,UserTypeEnum.MEMBER.getCode());
            if (sysUser != null){
                int result = thirdService.updateSysThirdByUserId(userId, sysUser.getUserId());
                if (result == 0){
                    return AjaxResult.error("绑定失败");
                }
                UserBindGsd userBindGsd = userBindGsdService.selectUserBindGsdByUserIdAndPlatform(userId, "wx_mini");
                if (userBindGsd != null){
                    userBindGsd.setUserId(sysUser.getUserId());
                    int i = userBindGsdService.updateUserBindGsd(userBindGsd);
                    if (i < 1){
                        log.error("login.getPhoneNumber(),userBindGsdService.updateUserBindGsd(userBindGsd);i ={}",i);
                        throw new CustomException("绑定失败");
                    }
                }
                //删除临时用户
                int count = memberService.deleteSysUserByUserId(userId);
                if (count == 0){
                    return AjaxResult.error("绑定失败");
                }
            }else{
                //根据第三方登录绑定的ID查询临时用户
                sysUser =memberService.selectMemberById(userId);
                if (sysUser== null){
                    return AjaxResult.error("用户不存在",ShowTypeEnum.用户.getValue());
                }
                sysUser.setPhonenumber(phoneNumber);
                memberService.updateMember(sysUser);
            }
            LoginUser loginUser = new LoginUser(sysUser);
            //根据用户ID获取别名
            UserAlias userAlias=userAliasService.selectMemberUserAliasByUserId(userId);
            boolean hasAlias=userAlias!=null&&StringUtils.isNotEmpty(userAlias.getAlias());
            //更新登录信息
            data.put("token",updateMemberToken(sysUser,loginUser,hasAlias?userAlias.getAlias():null));
            return AjaxResult.success("绑定成功",data);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }



    @ApiOperation("第三方登录")
    @PostMapping("/thirdLogin")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "第三方授权编码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userType", value = "用户类型 10=普通会员 20=配送员", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userAlias", value = "用户别名", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "platform", value = "第三方平台 platform = 'wx/qq/apple'", dataType = "String", paramType = "query"),
    })
    @ApiResponses({
        @ApiResponse(code = 200,message = "ok",response = LoginDto.class)
    })
    public AjaxResult thirdLogin(String code,String userType,String userAlias,String platform,@RequestParam(name = "deviceNo",defaultValue = "") String deviceNo) {

        if (userType.equals(UserTypeEnum.COURIER.getCode())) {
            return AjaxResult.error("请使用账号密码登录",ShowTypeEnum.用户.getValue());
        }

        try {
            SysThird third = thirdPlatformService.appToThirdInfo(code,platform);
            SysUser sysUser = memberService.selectMemberById(third.getUserId());
            LoginUser apiLoginUser = new LoginUser(sysUser);

            if (userType.equals(UserTypeEnum.MEMBER.getCode())) {
                apiLoginUser.setRole(ApiUtils.DEFAULT_ROLE_USER);
            }
            //如果没有绑定手机号码
            if(sysUser.getPhonenumber().isEmpty()) {
                userAliasService.setMemberUserAlias(userAlias,sysUser.getUserId(),null);
                return AjaxResult.success(LoginDto.getLoginDto(sysUser.getUserId(),"0",""));
            }

            try {
                String deviceBind = sysUser.getDeviceBind();
                if (!StringUtils.isEmpty(deviceNo) && DeviceBindEnum.TWO.getValue().equals(deviceBind)) {
                    bindDevice(deviceNo,sysUser.getPhonenumber(),sysUser);
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
            }
            //更新登录信息
            String token=updateMemberToken(sysUser,apiLoginUser,userAlias);
            return AjaxResult.success(LoginDto.getLoginDto(sysUser.getUserId(),"1",token));
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("授权登录失败:" + e.getMessage());
        }
    }

    @ApiOperation("绑定手机号")
    @PostMapping("/bindPhone")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "用户id", dataType = "String", paramType = "query")
    })
    @Transactional
    public AjaxResult bindPhone(String phone,String code,Long userId,@RequestParam(name = "deviceNo",defaultValue = "") String deviceNo){

        try {
            HashMap<String, String> data = Maps.newHashMap();

            if (!PhoneNumberUtils.isMobile(phone)){
                return AjaxResult.error("号码格式错误,请重新输入",ShowTypeEnum.用户.getValue());
            }
            String registerCode = smsService.getCode(phone, "register");
            if (!code.equals(registerCode)){
                return AjaxResult.error("验证码输入错误",ShowTypeEnum.用户.getValue());
            }
            smsService.remove(phone,"register");

            //根据手机号码查询用户
            SysUser sysUser = memberService.selectByPhone(phone,UserTypeEnum.MEMBER.getCode());
            if (sysUser != null){
                int result = thirdService.updateSysThirdByUserId(userId, sysUser.getUserId());
                if (result == 0){
                    return AjaxResult.error("绑定失败");
                }
                //删除临时用户
                int count = memberService.deleteSysUserByUserId(userId);
                if (count == 0){
                    return AjaxResult.error("绑定失败");
                }
            }else{
                //根据第三方登录绑定的ID查询临时用户
                sysUser =memberService.selectMemberById(userId);
                if (sysUser== null){
                    return AjaxResult.error("用户不存在",ShowTypeEnum.用户.getValue());
                }
                sysUser.setPhonenumber(phone);
                memberService.updateMember(sysUser);
            }

            try {
                String deviceBind = sysUser.getDeviceBind();
                if (!StringUtils.isEmpty(deviceNo) && DeviceBindEnum.TWO.getValue().equals(deviceBind)) {
                    bindDevice(deviceNo,phone,sysUser);
                }
            } catch (Exception e) {
                log.error(e.getMessage(),e);
            }

            LoginUser loginUser = new LoginUser(sysUser);
            //获取别名
            UserAlias userAlias=userAliasService.selectMemberUserAliasByUserId(userId);
            boolean hasAlias=userAlias!=null&&StringUtils.isNotEmpty(userAlias.getAlias());
            //更新登录信息
            data.put("token",updateMemberToken(sysUser,loginUser,hasAlias?userAlias.getAlias():null));
            return AjaxResult.success("绑定成功",data);
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("绑定失败");
        }
    }


    @LoginRequired
    @ApiOperation("退出登录")
    @GetMapping("/outLogin")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = Constants.TOKEN, value = "token标记", required = true)
    })
    public AjaxResult outLogin() {
        ApiUtils.outLogin(ServletUtils.getRequest().getHeader(Constants.TOKEN));
        return AjaxResult.success("退出成功",ShowTypeEnum.用户.getValue());
    }


    @ApiOperation("手机号注册")
    @PostMapping("/registerPhone")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "registerCode", value = "注册码", dataType = "String", paramType = "query"),
    })
    public AjaxResult registerPhone(String phone, String code, String password, String registerCode) {
        SysUser sysUser = memberService.selectByPhone(phone, UserTypeEnum.COURIER.getCode());
        if (sysUser != null) {
            return AjaxResult.error("手机号已存在",ShowTypeEnum.用户.getValue());
        }
        Shop shop = shopService.selectShopByInviteCode(registerCode);
        if (shop == null) {
            return AjaxResult.error("注册码不存在",ShowTypeEnum.用户.getValue());
        }
        String checkCode = smsService.getCode(phone, "register");
        if (StringUtils.isEmpty(checkCode) || !code.equals(checkCode)) {
            return AjaxResult.error("验证码错误",ShowTypeEnum.用户.getValue());
        }
        smsService.remove(phone, "register");
        sysUser=memberService.insertPhone(phone, password, registerCode, UserTypeEnum.COURIER.getCode());
        return toAjax(sysUser!=null?1:0);
    }

    @ApiOperation("忘记密码")
    @PostMapping("/forgetPassword")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "手机号", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "code", value = "验证码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "userType", value = "用户类型 10=普通会员 20=配送员", dataType = "String", paramType = "query"),
    })
    public AjaxResult forgetPassword(String phone, String code, String password, String userType) {
        if (StringUtils.isEmpty(userType)) {
            return AjaxResult.error("用户类型不能为空");
        }
        SysUser sysUser = memberService.selectByPhone(phone, userType);
        if (sysUser == null) {
            return AjaxResult.error("用户不存在",ShowTypeEnum.用户.getValue());
        }
        String checkCode = smsService.getCode(phone, "forget");
        if (StringUtils.isEmpty(checkCode) || !code.equals(checkCode)) {
            return AjaxResult.error("验证码错误",ShowTypeEnum.用户.getValue());
        }
        smsService.remove(phone, "forget");
        return toAjax(memberService.updatePassWord(phone, password, userType));
    }

    //获取openid
    public String getOpenId(String code){
        try {
            SysThirdPlatform thirdPlatform = sysThirdPlatformMapper.selectSysThirdPlatformByCode("wx_mini");

            Map<String, String> jscode2SessionQuerys = Maps.newHashMap();
            jscode2SessionQuerys.put("appid", thirdPlatform.getAppId());
            jscode2SessionQuerys.put("secret", thirdPlatform.getAppSecret());
            jscode2SessionQuerys.put("js_code", code);
            jscode2SessionQuerys.put("grant_type","authorization_code");
            HttpResponse jscode2SessionResponse = HttpUtils.doGet("https://api.weixin.qq.com", "/sns/jscode2session", null, jscode2SessionQuerys);
            Jscode2SessionBean jscode2Session = JSON.parseObject(EntityUtils.toString(jscode2SessionResponse.getEntity(), "UTF-8"),Jscode2SessionBean.class);
            if(StringUtils.isBlank(jscode2Session.getOpenid())&&StringUtils.isBlank(jscode2Session.getSessionKey())){
                throw new CustomException("未获取到用户openid 或 session:"+JSON.toJSONString(jscode2Session));
            }
            return jscode2Session.getOpenid();
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }


    @ApiOperation("支付宝授权码infoStr")
    @PostMapping("/alipayToAppAuth")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "platformType", value = "20(果果专员)", dataType = "String", paramType = "query"),
            @ApiImplicitParam(paramType = "header", dataType = "String", name = Constants.TOKEN, value = "token标记", required = true)
    })
    @LoginRequired
    public AjaxResult alipayToAppAuth(String platformType){
        try {
            String platform = "";
            if (platformType.equals(PlatformTypeEnum.ALIPAYGSD.getValue())){
                platform = "alipayByGsd";
            }else if (platformType.equals(PlatformTypeEnum.ALIPAYGGZY.getValue())){
                platform = "alipayByGgzy";
            }else {
                return AjaxResult.error(platformType+"平台不存在");
            }
            String alipayCode = thirdPlatformService.alipayToAppAuth(platform);
            return AjaxResult.success("操作成功",alipayCode);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error(e.getMessage());
        }
    }





    @ApiOperation("提现绑定")
    @PostMapping("/withdrawBind")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "platform", value = "platform(wx,alipay)", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "code",value = "wx是code,alipay是appAuthCode"),
            @ApiImplicitParam(paramType = "header", dataType = "String", name = Constants.TOKEN, value = "token标记", required = true)
    })
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_COURIER)
    public AjaxResult aliPayBind(String code,String platform) {
        try {
            if (platform.equals("wx")){
                thirdPlatformService.wxBind(code);
            }else if (platform.equals("alipay")){
                thirdPlatformService.alipayBind(code);
            }else {
                return AjaxResult.error(platform+"--平台不存在");
            }
            return AjaxResult.success("绑定成功");
        } catch (Exception e) {
            return AjaxResult.success(e.getMessage());
        }
    }
    @ApiOperation("提现解绑")
    @PostMapping("/untie")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "platform", value = "platform(wx,alipay)", dataType = "String", paramType = "query"),
            @ApiImplicitParam(paramType = "header", dataType = "String", name = Constants.TOKEN, value = "token标记", required = true)
    })
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_COURIER)
    public AjaxResult untie(Long id) {
        int result = userBindService.untieById(id);
        if (result <=0){
            return AjaxResult.error("解绑失败 ，result="+result);
        }
        return AjaxResult.success("解绑成功");
    }


    @ApiOperation("查询提现绑定信息")
    @PostMapping("/withdrawBindInfo")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "header", dataType = "String", name = Constants.TOKEN, value = "token标记", required = true)
    })
    @ApiResponses({
            @ApiResponse(code = 200,message = "",response = UserBindDto.class)
    })
    @LoginRequired(role = ApiUtils.DEFAULT_ROLE_COURIER)
    public AjaxResult withdrawBindInfo(){
                HashMap<String, UserBindDto> data = Maps.newHashMap();

        try{
 //跟据用户Id查询绑定信息
        List<UserBindDto> userBindDtos = userBindService.selectUserBindInfoByUserId(ApiUtils.getUserId());
        //查询微信或支付宝是否提现
        String key = (String) sysConfigService.selectConfigByKey("sys.withdraw.open");
        //解析字符串
        JSONObject jsonObject = JSON.parseObject(key);
        //封装
        if (userBindDtos !=null && userBindDtos.size()>0){
            //根据平台封装对象

            //微信支付宝都绑定
            if (userBindDtos.size()==2){
                for (UserBindDto userBindDto : userBindDtos) {
                    //wx
                    if (userBindDto.getPlatform().equals("wx")){
                        userBindDto.setOpen(jsonObject.getString("wx"));
                        data.put("wx",userBindDto);
                    }
                    //alipay
                    if (userBindDto.getPlatform().equals("alipay")){
                        userBindDto.setOpen(jsonObject.getString("alipay"));
                        data.put("alipay",userBindDto);
                    }
                }
            }
            //支付宝微信只绑定一个
            if (userBindDtos.size()==1){
                for (UserBindDto userBindDto : userBindDtos) {
                    //绑定了微信
                    if (userBindDto.getPlatform().equals("wx")){
                        userBindDto.setOpen(jsonObject.getString("wx"));
                        data.put("wx",userBindDto);
                        UserBindDto userBindDtoAli = new UserBindDto();
                        userBindDtoAli.setOpen(jsonObject.getString("alipay"));
                        userBindDtoAli.setIsBind("0");
                        data.put("alipay",userBindDtoAli);
                    }
                    //绑定了支付宝
                    if (userBindDto.getPlatform().equals("alipay")){
                        userBindDto.setOpen(jsonObject.getString("alipay"));
                        data.put("alipay",userBindDto);
                        UserBindDto userBindDtoWx = new UserBindDto();
                        userBindDtoWx.setIsBind("0");
                        userBindDtoWx.setOpen(jsonObject.getString("wx"));
                        data.put("wx",userBindDtoWx);
                    }
                }
            }

        }else {
            //如果查询为空,设置新对象,按照平台区分
            UserBindDto userBindDtoWx = new UserBindDto();
            userBindDtoWx.setIsBind("0");
            userBindDtoWx.setOpen(jsonObject.getString("wx"));
            data.put("wx",userBindDtoWx);
            UserBindDto userBindDtoAli = new UserBindDto();
            userBindDtoAli.setIsBind("0");
            userBindDtoAli.setOpen(jsonObject.getString("alipay"));
            data.put("alipay",userBindDtoAli);
        }
        }catch(Exception e){
            log.error("查询支付包微信绑定信息出错{}",e.getMessage());
            e.printStackTrace();
        }
       

        return AjaxResult.success("查询成功",data);
    }

    /**
     * 更新普通用户登录信息
     * @param sysUser
     * @param loginUser
     * @param alias
     * @return
     */
    private String updateMemberToken(SysUser sysUser,LoginUser loginUser,String alias){
        //清除旧的token令牌
        UserAlias userAlias = userAliasService.selectMemberUserAliasByUserId(sysUser.getUserId());
        if (userAlias != null && userAlias.getToken() != null) {
            ApiUtils.outLogin(userAlias.getToken());
        }
        //生成新的token令牌
        ApiUtils.createToken(loginUser);
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        //将用户登录信息保存到数据库中
        userAliasService.setMemberUserAlias(alias,sysUser.getUserId(),loginUser.getToken());
        return loginUser.getToken();
    }

    /**
     * 更新骑手登录信息
     * @param sysUser
     * @param apiLoginUser
     * @param alias
     * @return
     */
    private String updateCourierToken(SysUser sysUser,LoginUser apiLoginUser,String alias){

        apiLoginUser.setRole(ApiUtils.DEFAULT_ROLE_COURIER);
        //生成新的token令牌
        ApiUtils.createToken(apiLoginUser);
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(sysUser.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        //设置骑手 别名
        userAliasService.setCourierUserAlias(alias,sysUser.getUserId(),apiLoginUser.getToken());

        return apiLoginUser.getToken();
    }


    public void bindDevice(String deviceNo,String phone,SysUser sysUser){
        //校验设备是否绑定 true 绑定过 false 未绑定
        boolean b = deviceBindPhoneService.checkBindDeviceNo(deviceNo);
        if (!b){
            sysUser.setDeviceBind(DeviceBindEnum.ONE.getValue());
            memberService.updateMember(sysUser);
            DeviceBindPhone deviceBindPhone = new DeviceBindPhone();
            deviceBindPhone.setUserId(sysUser.getUserId());
            deviceBindPhone.setPhonenumber(phone);
            deviceBindPhone.setDeviceNo(deviceNo);
            deviceBindPhone.setCreateTime(new Date());
            boolean a = deviceBindPhoneService.insertDeviceBindPhone(deviceBindPhone);
            if (!a){
                log.error("设备绑定失败{}",a);
            }
        }
        if (b){
            sysUser.setDeviceBind(DeviceBindEnum.ZERO.getValue());
            memberService.updateMember(sysUser);
        }
    }
}
